//
//	HOME AUTOMATION GATEWAY PROJECT
//
//	IOBusApi - Callbacks
//
//  (c) 2008 mocom software GmbH & Co KG
//	for European Microsoft Innovation Center
//
//  $Author: volker $
//  $Date: 2009-09-25 14:43:44 +0200 (Fr, 25. Sep 2009) $
//  $Revision: 500 $
//
//  Microsoft dotNetMF Project
//  Copyright ©2001,2002,2003,2004 Microsoft Corporation
//  One Microsoft Way, Redmond, Washington 98052-6399 U.S.A.
//  All rights reserved.
//  MICROSOFT CONFIDENTIAL
//
//	IOBUS is (c) 2009 mocom software GmbH & Co KG
//
//-----------------------------------------------------------------------------

#include "hag_mocom_IOBus_IOBusApi_Callbacks.h"
#include "save/hag_mocom_IOBus_IOBusApi.h" 
#define DEF_NO_BASIC_TYPES
#include <iobus.h>

using namespace mocom::IOBus;

static bool g_CallbackEnableData;
static bool g_CallbackEnableError;
static CLR_RT_HeapBlock_NativeEventDispatcher *g_ContextData = NULL;
static CLR_RT_HeapBlock_NativeEventDispatcher *g_ContextError = NULL;
static bool g_cb_error_lock;
static bool g_cb_data_lock;


void CBDataCallbackAck()
{
	g_cb_data_lock=false;
}

void CBErrorCallbackAck()
{
	g_cb_error_lock=false;
}

static HRESULT InitializeDataCB( CLR_RT_HeapBlock_NativeEventDispatcher *pContext, UINT64 userData )
{
	g_ContextData  = pContext;
	return S_OK;
}

static HRESULT InitializeErrorCB( CLR_RT_HeapBlock_NativeEventDispatcher *pContext, UINT64 userData )
{
	g_ContextError  = pContext;
	return S_OK;
}

static HRESULT EnableDisableData( CLR_RT_HeapBlock_NativeEventDispatcher *pContext, bool fEnable )
{
	g_CallbackEnableData = fEnable;
	g_cb_data_lock = false;
	IOBusSetCycleMode((int)fEnable);
	return S_OK;
}

static HRESULT EnableDisableError( CLR_RT_HeapBlock_NativeEventDispatcher *pContext, bool fEnable )
{
	g_CallbackEnableError = fEnable;
	g_cb_error_lock = false;
	return S_OK;
}

static HRESULT CleanupIsrDriverData( CLR_RT_HeapBlock_NativeEventDispatcher *pContext )
{
	g_ContextData = NULL;
	g_CallbackEnableData = false;
	CleanupNativeEventsFromHALQueue( pContext );
	return S_OK;
}

static HRESULT CleanupIsrDriverError( CLR_RT_HeapBlock_NativeEventDispatcher *pContext )
{
	g_ContextError = NULL;
	g_CallbackEnableError = false;
	CleanupNativeEventsFromHALQueue( pContext );
	return S_OK;
}

void IOBusKickApiError( unsigned node, int error )
{
	GLOBAL_LOCK( irq );
	if ( g_CallbackEnableError && !g_cb_error_lock)
	{
		g_cb_error_lock=true;
		SaveNativeEventToHALQueue( g_ContextError, UINT32( node ), UINT32( error ) );
	}
}

void IOBusKickApi( unsigned cycle, int error )
{
	GLOBAL_LOCK( irq );
	if ( g_CallbackEnableData  && !g_cb_data_lock) 
	{
		g_cb_data_lock=true;
		SaveNativeEventToHALQueue( g_ContextData, UINT32( cycle ), UINT32( error ) );
	}
}

static const CLR_RT_DriverInterruptMethods g_IOBusDataCBMethods =

    { InitializeDataCB,
      EnableDisableData,
      CleanupIsrDriverData
    };

static const CLR_RT_DriverInterruptMethods g_IOBusErrorCBMethods =

    { InitializeErrorCB,
      EnableDisableError,
      CleanupIsrDriverError
    };

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_IOBusApi_DataCB =
{
	"IOBusApiDataCallback",
	DRIVER_INTERRUPT_METHODS_CHECKSUM,
	&g_IOBusDataCBMethods
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_IOBusApi_ErrorCB =
{
	"IOBusApiErrorCallback",
	DRIVER_INTERRUPT_METHODS_CHECKSUM,
	&g_IOBusErrorCBMethods
};
